home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / gamesrc / bg_src / bg_face.c < prev    next >
C/C++ Source or Header  |  1993-01-29  |  9KB  |  281 lines

  1. /*
  2.  *
  3.  *                     B  G  _  F  A  C  E  .  C
  4.  * BG.EXE face drawing file, this version 2nd May 1992.
  5.  *
  6.  */
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <math.h>
  11. #include "bg.h"
  12.  
  13. /***************************************************************************/
  14.  
  15. extern Disp_Cfg_t Disp_Cfg ;
  16. extern Screen_Const_t Grafs ;
  17.  
  18. /***************************************************************************/
  19. #define MAX_E_RAD   12          /* Maximum eye radius  */
  20. #define MIN_E_RAD    2          /* Minimum eye radius  */
  21. #define N_FO_PNTS    8          /* Face Outline Points */
  22. #define N_NO_PNTS    4          /* Nose Outline Points */
  23. #define M_PNTS      11          /* Mouth points        */
  24. #define N_TEETH  (M_PNTS-1)
  25. #define MAX_SMILE_OFFSET    12   /* % of whole face */
  26. #define MAX_TOOTH_SIZE      20   /* % of whole face */
  27.  
  28. /* The face is drawn on an imaginary grid of 100x100, with 0,0 at top left */
  29. typedef struct Face {
  30.     short Eye_X,  Eye_Y ;   /* X=offset from center, pixel coords */
  31.     short Ex_Rad, Ey_Rad ;  /* % sizes always */
  32.     short Mouth_Y,M_Wide ;
  33.     short S_Val,  T_Val ;     /* Smile and Tooth values */
  34.     short Outline [N_FO_PNTS][2] ;
  35.               /* Polyline for outline of face, will be closed */
  36.     short Nose_Line [N_NO_PNTS][2] ;
  37.               /* Polyline for outline of nose, may be closed or left open */
  38. } Face_t ;
  39.  
  40. static Face_t Faces[N_OPPS] = {
  41.     {20,40,              /* Eye x, Eye y */
  42.       5,4,
  43.      60,40,              /* Mouth y, wide, */
  44.      0,0,
  45.      {{20,5},{10,30},{20,70},{40,90},{60,90},{80,70},{90,30},{80,5}},
  46.      {{40,50},{40,50},{50,45},{60,50}}},
  47.  
  48.     {15,35,               /* Eye x, Eye y */
  49.       5,4,
  50.      70,35,               /* Mouth y, wide */
  51.      0,0,
  52.      {{30,10},{10,30},{10,70},{40,90},{60,90},{90,70},{90,30},{70,10}},
  53.      {{40,50},{40,50},{50,55},{60,50}}},
  54.  
  55.     {10,20,               /* Alberto */
  56.       5,4,
  57.      70,30,              /* Mouth_Y, Mouth_Wide */
  58.      0,0,
  59.      {{30,5},{10,20},{20,80},{50,93},{50,93},{80,80},{90,20},{70,5}},
  60.      {{50,30},{40,60},{50,65},{60,50}}},
  61.  
  62.     {20,30,
  63.       5,4,
  64.      70,40,
  65.      0,0,
  66.      {{40,10},{10,20},{20,80},{50,90},{50,90},{80,80},{90,20},{60,10}},
  67.      {{50,30},{50,30},{40,50},{60,50}}}  };
  68.  
  69.  
  70. /***************************************************************************/
  71.  
  72. void Init_Faces (void)
  73. /*
  74. PURPOSE: To change some of the face fields to pixel fields so we
  75.          don't have to recalculate them every time
  76. */
  77. {
  78.     short f,p,Dummy ;
  79.  
  80.     for (f = 0 ; f < N_OPPS ; f++) {
  81.         Faces[f].Eye_X  = ((Grafs.Logo_Wide * Faces[f].Eye_X)/100) ;
  82.         Faces[f].M_Wide = ((Grafs.Logo_Wide * Faces[f].M_Wide)/100) ;
  83.         Pixel_Transform (&Dummy,&Faces[f].Eye_Y) ;
  84.         Pixel_Transform (&Dummy,&Faces[f].Mouth_Y) ;
  85.         /* Transform face outline points */
  86.         for (p = 0 ; p < N_FO_PNTS ; p++) {
  87.             Pixel_Transform (&Faces[f].Outline[p][0],&Faces[f].Outline[p][1]) ;
  88.         }
  89.         /* Transform nose line points */
  90.         for (p = 0 ; p < N_NO_PNTS ; p++) {
  91.             Pixel_Transform (&Faces[f].Nose_Line[p][0],&Faces[f].Nose_Line[p][1]) ;
  92.         }
  93.     }
  94. }
  95.  
  96. /***************************************************************************/
  97.  
  98. void Pixel_Transform (short* x, short* y)
  99. /*
  100. PURPOSE: To transform the x and y from the 100x100 grid to the actual
  101.          pixel coords in the logo area.
  102. */
  103. {
  104.     (*x) = ((Grafs.Logo_Wide * (*x))/100) + Grafs.Logo_X ;
  105.     (*y) = ((Grafs.Logo_High * (*y))/100) + Grafs.Logo_Y ;
  106. }
  107.  
  108. /***************************************************************************/
  109.  
  110. void Draw_Eyes (short N_Vals, short o)
  111. /*
  112. PURPOSE: To draw the eyes of the opponent after he has seen the dice.
  113. */
  114. {
  115.     short Abs_X_Rad,Abs_Y_Rad ;
  116.  
  117.     /* Erase the old eyes */
  118.     Abs_X_Rad = (Faces[o].Ex_Rad * Grafs.Logo_Wide)/100 ;
  119.     Abs_Y_Rad = (Faces[o].Ey_Rad * Grafs.Logo_High)/100 ;
  120.  
  121.     /* Erase the old eyes */
  122.     Draw_Ellipse (Grafs.Logo_Center+Faces[o].Eye_X,Faces[o].Eye_Y,Abs_X_Rad,Abs_Y_Rad,BLACK) ;
  123.     Draw_Ellipse (Grafs.Logo_Center-Faces[o].Eye_X,Faces[o].Eye_Y,Abs_X_Rad,Abs_Y_Rad,BLACK) ;
  124.  
  125.     if (N_Vals == 4) {
  126.         Faces[o].Ex_Rad+=2 ;
  127.         Faces[o].Ey_Rad+=2 ;
  128.     } else {
  129.         Faces[o].Ex_Rad-=1 ;
  130.         Faces[o].Ey_Rad-=1 ;
  131.     }
  132.  
  133.     if (Faces[o].Ex_Rad < MIN_E_RAD) {
  134.         Faces[o].Ex_Rad = MIN_E_RAD ;
  135.     } else if (Faces[o].Ex_Rad > MAX_E_RAD) {
  136.         Faces[o].Ex_Rad = MAX_E_RAD ;
  137.     }
  138.     if (Faces[o].Ey_Rad < MIN_E_RAD) {
  139.         Faces[o].Ey_Rad = MIN_E_RAD ;
  140.     } else if (Faces[o].Ey_Rad > MAX_E_RAD) {
  141.         Faces[o].Ey_Rad = MAX_E_RAD ;
  142.     }
  143.  
  144.     Abs_X_Rad = (Faces[o].Ex_Rad * Grafs.Logo_Wide)/100 ;
  145.     Abs_Y_Rad = (Faces[o].Ey_Rad * Grafs.Logo_High)/100 ;
  146.     Draw_Ellipse (Grafs.Logo_Center+Faces[o].Eye_X,Faces[o].Eye_Y,Abs_X_Rad,Abs_Y_Rad,WHITE) ;
  147.     Draw_Ellipse (Grafs.Logo_Center-Faces[o].Eye_X,Faces[o].Eye_Y,Abs_X_Rad,Abs_Y_Rad,WHITE) ;
  148.  
  149.     Draw_Point (Grafs.Logo_Center+Faces[o].Eye_X,Faces[o].Eye_Y,WHITE) ;
  150.     Draw_Point (Grafs.Logo_Center-Faces[o].Eye_X,Faces[o].Eye_Y,WHITE) ;
  151. }
  152.  
  153. /***************************************************************************/
  154.  
  155. void Draw_Face_Outline (short o, short Col)
  156. /*
  157. PURPOSE: To draw the outline of the oth face, assuming it has already
  158. been transformed into the logo area. The nose is drawn too. The face
  159. outline is closed, the nose can be closed or open.
  160. */
  161. {
  162.     Draw_Pgon (N_FO_PNTS,Faces[o].Outline,Col) ;
  163.     Draw_Pline (N_NO_PNTS,Faces[o].Nose_Line,Col) ;
  164. }
  165.  
  166. /***************************************************************************/
  167.  
  168. void Redraw_Mouth (short o, short S_Val, short T_Val)
  169. /*
  170. S_Val must be between -100 and +100 (inclusive).
  171. T_Val must be between 0 qnd 100 (inclusive)
  172. MAX_SMILE_OFFSET is a positive % number. 100% means smile covers whole.
  173. face.
  174. */
  175. {
  176.     Draw_Mouth (o,Faces[o].S_Val,Faces[o].T_Val,BLACK) ; /* Erase old mouth */
  177.     Faces[o].S_Val = S_Val ;  /* Store new...  */
  178.     Faces[o].T_Val = T_Val ;  /* ...values.    */
  179.     Draw_Mouth (o,Faces[o].S_Val,Faces[o].T_Val,WHITE) ; /* Draw new mouth */
  180. }
  181.  
  182. /***************************************************************************/
  183.  
  184. void Draw_Mouth (short o, short S_Val, short T_Val, short Colour)
  185. /*
  186. PURPOSE: To draw a smiling or unsmiling mouth, with or without sharp
  187.          protruding teeth.
  188. */
  189. {
  190.     short  Mouth [M_PNTS][2] ;
  191.     short  Teeth [N_TEETH][2] ;
  192.     short  t,p ;
  193.     double Dsval ;
  194.  
  195.     if ((S_Val > 100) || (S_Val < (-100))) {
  196.         Error_Exit ("Bad S_Val") ;
  197.     }
  198.  
  199.     Dsval = ((double)S_Val/100.0)*(double)MAX_SMILE_OFFSET/100.0 ;
  200.     /* Dsval is now a fraction of a face */
  201.  
  202.     for (p = 0 ; p < M_PNTS ; p++) {
  203.         Mouth[p][0] = Grafs.Logo_Center - (Faces[o].M_Wide/2) + ((Faces[o].M_Wide*p)/(M_PNTS-1)) ;
  204.         Mouth[p][1] = Faces[o].Mouth_Y ;
  205.     }
  206.  
  207.     for (p = 0 ; p < M_PNTS ; p++) {
  208.         double Doff ;
  209.         Doff = -Dsval*cos ((double)p*TWO_PI/(double)(M_PNTS-1)) ;
  210.         /* Doff is as a fraction of a face */
  211.  
  212.         Mouth[p][1] = Mouth[p][1] + (short)(Doff*(double)Grafs.Logo_High) ;
  213.     }
  214.  
  215.     Draw_Pline (M_PNTS,Mouth,Colour) ;
  216.  
  217.     if (T_Val > 0) {
  218.         double T_Offset ;
  219.         T_Offset = (T_Val*(MAX_TOOTH_SIZE/100.0)*Grafs.Logo_High)/100.0 ;
  220.         for (t = 0 ; t < N_TEETH ; t++) {
  221.             /* Here we init the position of the points of the teeth */
  222.             Teeth[t][0] = (Mouth[t][0] + Mouth[t+1][0]) / 2 ;
  223.             Teeth[t][1] = (Mouth[t][1] + Mouth[t+1][1]) / 2 + (short)T_Offset ;
  224.         }
  225.         for (t = 0 ; t < N_TEETH ; t++) {
  226.             Draw_Line (Mouth[t][0],Mouth[t][1],
  227.                        Teeth[t][0],Teeth[t][1],Colour) ;
  228.             Draw_Line (Mouth[t+1][0],Mouth[t+1][1],
  229.                        Teeth[t][0],Teeth[t][1],Colour) ;
  230.         }
  231.     }
  232. }
  233.  
  234. /***************************************************************************/
  235. #if DRODBAR
  236. void Redraw_Eyebrows (short o, short Eb_Val)
  237. {
  238. }
  239.  
  240. /***************************************************************************/
  241.  
  242. void Draw_Eyebrows (short o, short Eb_Val, short Colour)
  243. {
  244. }
  245. #endif
  246. /***************************************************************************/
  247.  
  248. void Draw_Face (Layout_t Me, Layout_t Him, short o)
  249. /*
  250. A decent range seems to be between -50 and +50
  251. */
  252. {
  253.     short Pips ;
  254.  
  255.     Pips = Pip_Count_Diff (Me,Him) ;
  256.     if (Pips > 50) {
  257.         Pips = 50 ;
  258.     } else if (Pips < (-50)) {
  259.         Pips = (-50) ;
  260.     }
  261.     Redraw_Mouth (o,Pips,(short)Aggression_Score(Me,Him)) ;
  262.     Draw_Face_Outline (o, WHITE) ;
  263. }
  264.  
  265. /***************************************************************************/
  266.  
  267. void Show_Opponents_Face (Layout_t Layouts[2], Player_t Hum, short O_Index)
  268. /*
  269. PURPOSE: To show the opponents joy or anger as he contemplates his
  270.           position.
  271. */
  272. {
  273.     if (Hum == BLACK_PLAYER) {
  274.         Draw_Face (Layouts[WHITE_PLAYER], Layouts[BLACK_PLAYER], O_Index) ;
  275.     } else {
  276.         Draw_Face (Layouts[BLACK_PLAYER], Layouts[WHITE_PLAYER], O_Index) ;
  277.     }
  278. }
  279.  
  280. /***************************************************************************/
  281.